# -*- coding: utf-8 -*-
import traceback
from flask import current_app as app
from flask import g, render_template, flash, session, redirect, url_for, request
from flask.blueprints import Blueprint
from sqlalchemy.sql.expression import and_
from sqlalchemy.orm.exc import NoResultFound
from wtforms import Form, HiddenField, TextField, SelectField, DateField, validators

from sys2do.views import BasicView
from sys2do.util.decorator import templated, loginRequired, allPermission, \
    anyPermission
from sys2do.util.common import _g, _gld, _gl
from sys2do.constant import MSG_NO_SUCH_ACTION, MESSAGE_ERROR, TAB_FLAG, \
    TAB_SETTING, MSG_SAVE_SUCC, MESSAGE_INFO, MSG_SERVER_ERROR, LOG_TYPE_CREATE
from sys2do.model import User, Group, Permission, db, qry, SysLog
from sys2do.util.logic_helper import getCurrentUserID, getCurrentShopProfile
from sys2do.util.wt_helper import MyDateField


error_page = lambda code : lambda error : render_template( "%d.html" % code )


__all__ = ['bpSys']

bpSys = Blueprint( 'bpSys', __name__ )

@bpSys.before_request
def addActivetab():    session[TAB_FLAG] = TAB_SETTING

class SysView( BasicView ):

    template_folder = 'sys'

    @templated( "index.html" )
    @anyPermission( ['USER_VIEW', 'GROUP_VIEW', ] )
    @loginRequired
    def index( self ):
        return {}


    @anyPermission( ['USER_VIEW', 'GROUP_VIEW', ] )
    @loginRequired
    def obj_index( self ):
        t = _g( 't' )
        if t not in ['USR', 'GRP', 'PRM']:
            flash( MSG_NO_SUCH_ACTION, MESSAGE_ERROR )
            return redirect( url_for( '.view' ) )

        cds = []

        if t == 'USR' :
            spobj = getCurrentShopProfile()
            tn = 'user.html'
            obj, form = User, USRSrhForm( request.form )
            cds.append( obj.active == 0 )
            cds.append( obj.groups.any( Group.id.in_( spobj.groupIDs or [] ) ) )
            if form.name.data : cds.append( obj.name.like( '%%%s%%' % form.name.data ) )
            if form.email.data : cds.append( obj.email.like( '%%%s%%' % form.email.data ) )
            if form.phone.data : cds.append( obj.phone.like( '%%%s%%' % form.phone.data ) )
            if form.mobile.data : cds.append( obj.mobile.like( '%%%s%%' % form.mobile.data ) )
            if form.createTimeFrom.data : cds.append( obj.createTime > form.createTimeFrom.data )
            if form.createTimeTo.data : cds.append( obj.createTime < form.createTimeTo.data )
        elif t == 'GRP':
            spobj = getCurrentShopProfile()
            tn = 'group.html'
            obj, form = Group, GRPSrhForm( request.form )
            cds.append( obj.active == 0 )
            cds.append( obj.id.in_( spobj.groupIDs or [] ) )
            if form.name.data : cds.append( obj.name.like( '%%%s%%' % form.name.data ) )
            if form.createTimeFrom.data : cds.append( obj.createTime > form.createTimeFrom.data )
            if form.createTimeTo.data : cds.append( obj.createTime < form.createTimeTo.data )
        elif t == 'PRM':
            tn = 'permission.html'
            obj, form = Permission, PRMPSrhForm( request.form )
            cds.append( obj.active == 0 )
            if form.name.data : cds.append( obj.name.like( '%%%s%%' % form.name.data ) )
            if form.createTimeFrom.data : cds.append( obj.createTime > form.createTimeFrom.data )
            if form.createTimeTo.data : cds.append( obj.createTime < form.createTimeTo.data )

        result = obj.all( conditions = cds, order_by = obj.name )
        template_name = "%s/%s" % ( self.template_folder.replace( '.', '/' ), tn )
        return render_template( template_name, result = result, form = form, t = t )



    @anyPermission( ['USER_CREATE', 'GROUP_CREATE', ] )
    @loginRequired
    def obj_add( self ):
        t = _g( 't' )
        if t not in ['USR', 'GRP', 'PRM']:
            flash( MSG_NO_SUCH_ACTION, MESSAGE_ERROR )
            return redirect( url_for( '.view' ) )

        params = {}
        if t == 'USR' :
            tn = 'user_add.html'
            spobj = getCurrentShopProfile()
            params['groups'] = [Group.get( gid ) for gid in spobj.groupIDs]


        elif t == 'GRP':
            tn = 'group_add.html'

            uid = getCurrentUserID()
            user = User.get( uid )
            permissions = {}
            for g in user.groups:
                for p in g.permissions:
                    if p.id not in permissions : permissions[p.id] = p.name
            params['permissions'] = permissions

        elif t == 'PRM':
            tn = 'permission_add.html'
        template_name = "%s/%s" % ( self.template_folder.replace( '.', '/' ), tn )
        return render_template( template_name, t = t, **params )



    def obj_save( self ):
        t = _g( 't' )
        if t not in ['USR', 'GRP', 'PRM']:
            flash( MSG_NO_SUCH_ACTION, MESSAGE_ERROR )
            return redirect( url_for( '.view' ) )
        try:
            if t == 'USR' :
                params = _gld( 'name', 'email', 'password', 'phone', 'mobile' )
                obj = User.create( params )
                if _g( 'groupID' ) :    # add user to the shop's user group
                    grp = Group.get( _g( 'groupID' ) )
                    if grp : grp.users.append( obj )
            elif t == 'GRP':
                params = _gld( 'name', 'displayName', 'desc' )
                obj = Group.create( params )
                prms = _gl( 'permissions' )
                if prms :
                    if type( prms ) != list : prms = [prms, ]
                    obj.permissions = qry( Permission ).filter( Permission.id.in_( prms ) ).all()
                db.add( obj )
                db.flush()
                spobj = getCurrentShopProfile()
                spobj.groupIDs = ( spobj.groupIDs or [] ) + [obj.id, ]

            elif t == 'PRM':
                params = _gld( 'name', 'desc' )
                obj = Permission.create( params )
            db.add( obj )
            db.flush()
            db.add( SysLog( refClz = obj.__class__.__name__, type = LOG_TYPE_CREATE, refID = obj.id, ) )
            db.commit()
            flash( MSG_SAVE_SUCC, MESSAGE_INFO )
        except:
            traceback.print_exc()
            db.rollback()
            flash( MSG_SERVER_ERROR, MESSAGE_ERROR )
        return redirect( url_for( '.view', action = 'obj_index', t = t ) )

bpSys.add_url_rule( '/', view_func = SysView.as_view( 'view' ), defaults = {'action':'index'} )
bpSys.add_url_rule( '/<action>', view_func = SysView.as_view( 'view' ) )




#===============================================================================
# form class
#===============================================================================



class USRSrhForm( Form ):
    name = TextField( u'用户名称', [validators.Length( min = 1, max = 25 )] )
    email = TextField( u'电子邮箱', [validators.Length( min = 1, max = 25 )] )
    phone = TextField( u'电话号码', [validators.Length( min = 1, max = 25 )] )
    mobile = TextField( u'手机', [validators.Length( min = 1, max = 25 )] )
    createTimeFrom = MyDateField( u'创建时间(开始)' )
    createTimeTo = MyDateField( u'创建时间(结束)' )

class GRPSrhForm( Form ):
    name = TextField( u'组别名称', [validators.Length( min = 1, max = 25 )] )
    createTimeFrom = MyDateField( u'创建时间(开始)' )
    createTimeTo = MyDateField( u'创建时间(结束)' )

class PRMPSrhForm( Form ):
    name = TextField( u'权限名称', [validators.Length( min = 1, max = 25 )] )
    createTimeFrom = MyDateField( u'创建时间(开始)' )
    createTimeTo = MyDateField( u'创建时间(结束)' )
